home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of Amiga
/
World of Amiga.iso
/
archive
/
assembly
/
lsd-lo.s.lha
/
FileLoader.Src
< prev
next >
Wrap
Text File
|
1980-01-18
|
11KB
|
569 lines
* EXAMPLE OF USE!
move.w #$4000,$dff09a ;disable irqs
jsr INIT_DISK ;set up
move.l #loadspace,a5 ;address of load
move.l #filename,a6 ;address of filename
moveq #0,d7 ;load mode set
jsr LOAD_FILE
tst.w d7 ;check for failure
beq.s fileok
move.w #$7fff,d0 ;red screen = error
erlp move.w #$f00,$dff180
dbf d0,erlp
fileok jsr MOTOR_OFF
move.w #$c000,$dff09a
rts
loadspace dcb.l $8000,$00
filename dc.b "vegetables/onion",$00
*****************************************************************************
* System Independant AmigaDos File Loader V1.1 - 26/4/94 *
*--------------------------------------------------------------*
* By PHIL RUSTON AKA:PHIL!94/LSD *
* Call: "INIT_DISK" before you load for the 1st time ever!!!
* To LOAD A FILE Set:-
* A6 - Address of 0 terminated filename (no path/can include directories).
* A5 - Load address.
* D7 - 0 = Load, 1 = Search and Return file length in A5 only.
* Then call: "LOAD_FILE"
* Call "MOTOR_OFF" when finished loading for a while!!
* A5 returns last byte address of file + 1
* D7 returns 0 is load OK. Or one of the following errors:
* 01 = No speed signal from motor (disk removed while loading?)
* 02 = No DMA transfer time out (bad disk/ '' '')
* 03 = Disk removed from drive (for you to issue requester)
* 04 = Can't find that disk block (disk corrupt)
* 05 = Wrong track marker ID ('')
* 06 = Checksum error on disk block ('')
* 07 = Block requested out of range ('')
* 08 = Not a file (Its a directory!)
* 09 = File not found (obvious!)
*******************************************************************************
section loadcode,code
DRIVE equ 0
INIT_DISK movem.l d7/a1/a2,-(a7)
bsr motor_off
move.l #$bfd000,a1
move.l #variables,a2
bclr #drive+3,$100(a1)
bsr initialize_drive
bsr motor_off
movem.l (a7)+,d7/a1/a2
rts
LOAD_FILE movem.l d0-d6/a0-a4/a6,-(a7)
bsr Find_file
tst.b error(a2)
beq.s no_error
bsr motor_off
move.w #1000,d7
bsr cia_wait
no_error moveq #0,d7
move.b error(a2),d7
movem.l (a7)+,d0-d6/a0-a4/a6
rts
MOTOR_OFF movem.l d7/a1-a2,-(a7)
move.l #$bfd000,a1
move.l #variables,a2
clr.b motor(a2)
move.b #$ff,$100(a1)
move.b #$87,$100(a1)
bsr wait1msec
move.b #$ff,$100(a1)
movem.l (a7)+,d7/a1-a2
rts
*********************
* Get Main Root Dir *
*********************
Find_file move.l #$bfd000,a1
move.l #variables,a2
move.l a5,load_address(a2)
clr.b error(a2)
move.b d7,mode(a2)
move.l #block_buffer,a0 ;get disk's root dir.
move.w #880,d0
bsr Get_block
tst.b error(a2)
bne file_eror
******************************
* Find File's Root Directory *
******************************
Find_files_root_dir_loop
move.l a6,a4
moveq #0,d0
dir_loop move.b (a4),d7 ;find file's root dir
beq.s root_dir
cmpi.b #"/",d7 ;and get length of subdir name
beq.s oblique ;if required.
addq.w #1,a4
addq.w #1,d0
bra dir_loop
oblique move.w d0,d7 ;d0 = dir name length
move.w d0,d6
subq.w #1,d7
bsr hash_name ;hash dir name into d0
lsl.w #2,d0
move.l $18(a0,d0.w),d0 ;header block for this hash
beq file_not_found
get_dir_header
bsr Get_block
tst.b error(a2)
bne file_eror
bsr compare_names
tst.w d7
beq.s next_in_hash_chain
addq.w #1,a4
move.l a4,a6
bra find_files_root_dir_loop
next_in_hash_chain
move.l $1f0(a0),d0
bne get_dir_header
bra file_not_found
**************************
* Locate The File Itself *
**************************
root_dir move.w d0,d7 ;length of file name
move.w d0,d6
subq.w #1,d7
bsr hash_name
lsl.w #2,d0
move.l $18(a0,d0.w),d0 ;header block number for this hash
beq file_not_found
get_header
bsr Get_block
tst.b error(a2)
bne file_eror
bsr compare_names
tst.w d7
bne.s correct_file_header
move.l $1f0(a0),d0 ;any more in hash chain?
bne get_header
bra file_not_found
correct_file_header
cmpi.l #-3,$1fc(a0) ;make sure its a file header
beq.s file_header
move.b #8,error(a2) ;not a file header-error 8
bra file_eror
file_header
move.l load_address(a2),a5
move.l $144(a0),d6 ;length of file.
tst.b mode(a2)
beq.s transfer
move.l d6,a5
rts
transfer
subq.l #1,d6
transfer_loop
move.l $10(a0),d0 ;next block location
beq file_not_found
bsr Get_block
tst.b error(a2)
bne file_eror
****************************************
* Download data to file's load address *
****************************************
lea $18(a0),a3 ;1st data longword in dos_block
moveq #$79,d7
make_file subq.l #4,d6
bmi.s last_bytes
move.l (a3)+,(a5)+
dbf d7,make_file
bra transfer_loop
last_bytes
addq.w #4,d6
lb_loop move.b (a3)+,(a5)+
dbf d6,lb_loop
rts
file_not_found
move.b #9,error(a2) ;file not found-error 8
file_eror rts
*****************************
* File Load Called Routines *
*****************************
hash_name move.l a6,a3
hash_loop moveq #0,d2 ;hash file name at a6
move.b (a3)+,d2 ;length-1 in d7.
cmpi.b #$60,d2
bls.s capital
cmpi.b #$7a,d2
bhi.s capital
subi.b #$20,d2
capital mulu #13,d0
add.l d2,d0
andi.l #$7ff,d0
dbf d7,hash_loop
divu #72,d0
swap d0 ;d0=hash number
rts
compare_names
moveq #0,d7
cmp.b $1b0(a0),d6 ;d6=length of name being tested
bne.s name_fail
move.w d6,d5
move.l a6,a3
lea $1b1(a0),a5
subq.w #1,d5
comp_loop move.b (a3)+,d1 ;Case desensitize filename
move.b (a5)+,d2 ;compare.
andi.b #$df,d1
andi.b #$df,d2
cmp.b d1,d2
dbne d5,comp_loop
tst.w d5
bpl.s name_fail
moveq #1,d7
name_fail rts
*****************************************************************************
****************************
* Get a block into buffer! *
****************************
* D0 will equal block number required ($0 - $6df)
Get_block movem.l a0-a6/d0-d7,-(a7)
move.w #$0504,attempts(a2)
andi.l #$ffff,d0
cmpi.w #$6df,d0 ;check range
bls blk_in_range
move.b #7,error(a2)
bra no_reload
blk_in_range
move.w d0,d1
divu #11,d1 ;what cylinder is that on?
tst.b motor(a2)
beq.s reload
cmp.b trackside(a2),d1
beq.s Trksde_in ;that track is already in.
Reload bsr Fetch_trackside ;loads track required
tst.b error(a2)
bne No_reload
Trksde_in clr.b error(a2)
move.l #MFMbuffer,a3
lea $31fe(a3),a0
find_sync move.w #$4489,d7
fs_loop cmp.w (a3)+,d7
beq found_sync
cmp.l a0,a3
bls.s fs_loop
move.b #4,error(a2) ;couldnt find that sector-error 4
bra MFM_error
found_sync
cmp.w (a3),d7
beq.s syncstart
subq.w #2,a3
syncstart lea $2a(a3),a4 ;Check header checksum.
bsr decode_lw
move.l $2(a3),d3
move.l $6(a3),d4
andi.l #$55555555,d3
andi.l #$55555555,d4
eor.l d4,d3
cmp.l d3,d5
bne Not_sector
lea $2(a3),a4 ;Track mark = Head position?
bsr decode_lw
move.l d5,d4
swap d4
cmp.b trackside(a2),d4
beq Track_mark_ok
move.b #5,error(a2) ;wrong track mark - error 5
bra MFM_error
Track_mark_ok
lsr.w #8,d5 ;Is this the sector required?
move.l d1,d7
swap d7
cmp.b d5,d7
beq.s Found_block
Not_sector
add.w #$430,a3 ;loop until find correct sector
bra find_sync
Found_Block
moveq #0,d2 ;Put converted mfm at dest addr.
move.l #$55555555,d7
move.l #block_buffer,a6
lea $3a(a3),a4
lea $23a(a3),a5
moveq #$7f,d3
next_lw move.l (a4)+,d6
move.l (a5)+,d5
and.l d7,d6
and.l d7,d5
eor.l d6,d2 ;update checksum
eor.l d5,d2
add.l d6,d6
or.l d5,d6
move.l d6,(a6)+
dbf d3,next_lw
sub.w #$208,a4
bsr decode_lw
cmp.l d5,d2
beq.s no_reload
move.b #6,error(a2) ;checksum error - error 6
MFM_error subq.b #1,attempts(a2)
bne Reload
bsr initialize_drive
move.b #5,attempts(a2)
subq.b #1,attempts+1(a2)
bne Reload
No_reload movem.l (a7)+,a0-a6/d0-d7
rts
*****************************************************************************
*********************
* MFM Track loader! *
*********************
* D1 will equal trackside 0 - 159
Fetch_trackside
movem.l a0/d0-d3,-(a7)
move.l #$dff000,a0
clr.b error(a2)
tst.b motor(a2)
bne.s motor_on
move.b #$ff,$100(a1)
bclr #drive+3,$100(a1)
bsr wait1msec
btst #2,$1001(a1)
bne.s start_mot
btst #1,trackside(a2)
beq.s inchk
bsr stepout
bra.s stepchk
inchk bsr stepin
stepchk btst #2,$1001(a1)
beq.s no_disk
bsr initialize_drive
start_mot move.b #$7f,$100(a1) ;drive selected / motor on.
bclr #drive+3,$100(a1)
move.b #1,motor(a2)
move.w #200,d2 ;wait for correct motor speed.
wdskrdy moveq #10,d7
bsr cia_wait
btst #5,$1001(a1)
dbeq d2,wdskrdy
tst.w d2
bpl motor_on
move.b #1,error(a2) ;no speed signal - error 1
bra trackload_end
motor_on btst #2,$1001(a1) ;disk removed?
bne.s disk_in
no_disk move.b #3,error(a2)
bra trackload_end
disk_in move.w d1,d3
lsr.b #1,d3 ;select disk side to load from.
bcc.s head1
bclr #2,$100(a1)
bra checkhead
head1 bset #2,$100(a1)
checkhead move.b trackside(a2),d2 ;ensure head is over correct
lsr.b #1,d2 ;track
cmp.b d2,d3
beq.s headok
bls.s seekout
bsr stepin
bra.s checkhead
seekout bsr stepout
bra.s checkhead
headok move.b d1,trackside(a2)
move.w #$2,$9c(a0) ;clear disk block irq flag
moveq #18,d7 ;settle wait.
bsr cia_wait
move.l #mfmbuffer,$20(a0)
move.w #$4000,$24(a0)
move.w #$8010,$96(a0) ;enable dma
move.w #$6800,$9e(a0)
move.w #$9500,$9e(a0)
move.w #$4489,$7e(a0) ;sync
move.w #$9900,$24(a0)
move.w #$9900,$24(a0)
move.w #200,d2
waitdirq moveq #10,d7
bsr cia_wait
btst #1,$1f(a0)
dbne d2,waitdirq
tst.w d2
bpl.s read_ok
move.b #2,error(a2) ;No DMA finish-Time Out-error 2
read_ok move.w #$4000,$24(a0)
move.w #$10,$96(a0) ;disable dma
Trackload_end
movem.l (a7)+,a0/d0-d3
rts
*******************************************************************************
decode_lw move.l #$55555555,d7 ;decode two consec mfm longwords
move.l (a4),d5 ;into d5
move.l $4(a4),d4
and.l d7,d5
and.l d7,d4
add.l d5,d5
or.l d4,d5
rts
stepout subq.b #2,trackside(a2)
bset #1,$100(a1)
bra.s step
stepin addq.b #2,trackside(a2)
bclr #1,$100(a1)
step bsr.s shortwait
bclr #0,$100(a1)
bsr.s shortwait
bset #0,$100(a1)
moveq #4,d7
bsr cia_wait
rts
shortwait
nop
nop
nop
nop
rts
initialize_drive
btst #$4,$1001(a1)
beq.s gottrack0
bsr.s stepout
bra.s initialize_drive
gottrack0 clr.b trackside(a2)
move.w #20,d7
bsr cia_wait
rts
wait1msec moveq #1,d7
cia_wait move.b #$08,$f00(a1) ;set one shot / stop timer.
move.b #$cc,$600(a1) ;set timer lo
move.b #$02,$700(a1) ;set timer hi (starts counter)
ciawlp2 btst #0,$f00(a1) ;wait for ciab timer b to timeout
bne.s ciawlp2
subq.w #1,d7
bne.s cia_wait ;d1 = milliseconds to wait.
rts
*******************************************************************************
trackside equ $0
error equ $1
motor equ $2
mode equ $3
attempts equ $4
load_address equ $6
variables dcb.w $5,$0000
block_buffer
dcb.w $100,$0000
section chipstuff,data_c
mfmbuffer dcb.w $1910,$0000
*******************************************************************************